package com.goosuncc.gscc.sdk;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.goosuncc.gscc.sdk.command.BindCustomerBatchLinkCommand;
import com.goosuncc.gscc.sdk.command.GetAgentReportCommand;
import com.goosuncc.gscc.sdk.command.GetAllUserAgentCommand;
import com.goosuncc.gscc.sdk.command.GetCustomerContactHistoryCommand;
import com.goosuncc.gscc.sdk.command.GetExtColumnCommand;
import com.goosuncc.gscc.sdk.command.HelloWorldCommand;
import com.goosuncc.gscc.sdk.command.ImportCustomerBatchCommand;
import com.goosuncc.gscc.sdk.command.ImportCustomerCommand;
import com.goosuncc.gscc.sdk.command.internal.AbstractApiCommand;
import com.goosuncc.gscc.sdk.command.internal.AbstractApiResponse;
import com.goosuncc.gscc.sdk.command.response.BindCustomerBatchLinkResponse;
import com.goosuncc.gscc.sdk.command.response.GetAgentReportResponse;
import com.goosuncc.gscc.sdk.command.response.GetAllUserAgentResponse;
import com.goosuncc.gscc.sdk.command.response.GetCustomerContactHistoryResponse;
import com.goosuncc.gscc.sdk.command.response.GetExtColumnResponse;
import com.goosuncc.gscc.sdk.command.response.HelloWorldResponse;
import com.goosuncc.gscc.sdk.command.response.ImportCustomerBatchResponse;
import com.goosuncc.gscc.sdk.command.response.ImportCustomerResponse;
import com.goosuncc.gscc.sdk.command.response.bean.CustomerBatch;
import com.goosuncc.gscc.sdk.command.response.bean.ViewCustomer;
import com.goosuncc.gscc.sdk.util.GsccSignUtil;

public class GsccServer {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private String gsccUrl;
	private String apiSecret;
	private int connectTimeout = 2000;
	private int readTimeout = 2000;

	private SSLContext sslContext = null;

	public GsccServer() {
		try {
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, trustAllCerts, new SecureRandom());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public GsccServer(String gsccUrl, String apiSecret, int connectTimeout, int readTimeout) {
		this.gsccUrl = gsccUrl;
		this.apiSecret = apiSecret;
		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
		try {
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, trustAllCerts, new SecureRandom());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public <T extends AbstractApiResponse> T sendCommand(AbstractApiCommand apiCommand, Class<T> clazz) {

		T t = null;

		try {

			String commandString = apiCommand.toJsonString();
			logger.debug("commandString=" + commandString);
//			System.out.println("commandString=" + commandString);

			String connection = "?";
			if(gsccUrl.contains("?")) {
				connection = "&";
			}
			
			String urlString = gsccUrl + connection + "sign=" + GsccSignUtil.sign(commandString, apiSecret);
			logger.debug("request url=" + urlString);
			logger.debug("request body=" + commandString);
			URL url = new URL(urlString);

			HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
			HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
			conn.setConnectTimeout(connectTimeout);
			conn.setReadTimeout(readTimeout);
			conn.setDoOutput(true);
			conn.connect();

			// send http request
			OutputStream outStream = conn.getOutputStream();
			outStream.write(commandString.getBytes());
			outStream.flush();
			outStream.close();

			// receive http response
			StringBuilder result = new StringBuilder();
			BufferedReader r = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = null;
			while ((line = r.readLine()) != null) {
				result.append(line);
			}
			t = JSON.parseObject(result.toString(), clazz);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}

	// private <T extends AbstractApiResponse> T sendCommand(AbstractApiCommand
	// apiCommand, Class<T> clazz) {
	// String commandString = apiCommand.toJsonString();
	// logger.debug("commandString="+commandString);
	// String url = gsccUrl + "?sign=" + GsccSignUtil.sign(commandString,
	// apiSecret);
	// logger.debug("request url="+url);
	// logger.debug("request body="+commandString);
	// HttpRequest httpRequest =
	// HttpRequest.post(url).contentType("application/json;charset=UTF-8")
	// .connectTimeout(connectTimeout).readTimeout(readTimeout).send(commandString);
	// httpRequest.trustAllCerts();
	// String body = httpRequest.body();
	// logger.debug("RESPONSE BODY="+body);
	// T t = JSON.parseObject(body, clazz);
	//
	// return t;
	// }

	public String getGsccUrl() {
		return gsccUrl;
	}

	public void setGsccUrl(String gsccUrl) {
		this.gsccUrl = gsccUrl;
	}

	public String getApiSecret() {
		return apiSecret;
	}

	public void setApiSecret(String apiSecret) {
		this.apiSecret = apiSecret;
	}

	public int getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	public int getReadTimeout() {
		return readTimeout;
	}

	public void setReadTimeout(int readTimeout) {
		this.readTimeout = readTimeout;
	}

	/**
	 * 测试DEMO
	 */
	public HelloWorldResponse helloWorldCommand() {
		HelloWorldCommand apiCommand = new HelloWorldCommand();
		HelloWorldResponse response = this.sendCommand(apiCommand, HelloWorldResponse.class);
		return response;
	}
	
	/**
	 * 获取用户坐席
	 */
	public GetAllUserAgentResponse getAllUserAgentCommand(Long id,String loginName,Long jobNumber,String nickName) {
		GetAllUserAgentCommand apiCommand = new GetAllUserAgentCommand(id,loginName,jobNumber,nickName);
		GetAllUserAgentResponse response = this.sendCommand(apiCommand, GetAllUserAgentResponse.class);
		return response;
	}
	
	/**
	 * 获取客户沟通历史记录
	 * 
	 * @return
	 */
	public GetCustomerContactHistoryResponse getCustomerContactHistory(String customerPhoneNumber,Long startTime,Integer limit) {
		GetCustomerContactHistoryCommand apiCommand = new GetCustomerContactHistoryCommand(customerPhoneNumber,startTime,limit);
		GetCustomerContactHistoryResponse response = this.sendCommand(apiCommand, GetCustomerContactHistoryResponse.class);
		return response;
	}
	
	/**
	 * 获取扩展字段
	 */
	public GetExtColumnResponse getExtColumn(String tableName) {
		GetExtColumnCommand apiCommand = new GetExtColumnCommand(tableName);
		GetExtColumnResponse response = this.sendCommand(apiCommand, GetExtColumnResponse.class);
		return response;
	}

	/**
	 * 获取座席话务报表
	 */
	public GetAgentReportResponse getAgentReportCommand(String agentAid,String agentName,String reportDuration,String orderByType,String start_stamp,String end_stamp,Boolean showAllData) {
		GetAgentReportCommand apiCommand = new GetAgentReportCommand(agentAid,agentName,reportDuration,orderByType,start_stamp,end_stamp,showAllData);
		GetAgentReportResponse response = this.sendCommand(apiCommand, GetAgentReportResponse.class);
		return response;
	}
	
	/**
	 * 导入客户
	 */
	public ImportCustomerResponse importCustomerCommand(List<ViewCustomer> viewCustomerList,Boolean overWriteData) {
		ImportCustomerCommand apiCommand = new ImportCustomerCommand(viewCustomerList,overWriteData);
		ImportCustomerResponse response = this.sendCommand(apiCommand, ImportCustomerResponse.class);
		return response;
	}
	
	/**
	 * 导入批次
	 */
	public ImportCustomerBatchResponse importCustomerBatchCommand(List<CustomerBatch> customerBatchList) {
		ImportCustomerBatchCommand apiCommand = new ImportCustomerBatchCommand(customerBatchList);
		ImportCustomerBatchResponse response = this.sendCommand(apiCommand, ImportCustomerBatchResponse.class);
		return response;
	}
	
	/**
	 * 绑定客户批次关系
	 */
	public BindCustomerBatchLinkResponse bindCustomerBatchLinkCommand(List<Long> customerIdList,CustomerBatch customerBatch,Boolean isNewBatch) {
		BindCustomerBatchLinkCommand apiCommand = new BindCustomerBatchLinkCommand(customerIdList,customerBatch,isNewBatch);
		BindCustomerBatchLinkResponse response = this.sendCommand(apiCommand, BindCustomerBatchLinkResponse.class);
		return response;
	}
	
	///////////// http https ////////////////
	private static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	} };

	private class NullHostNameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String arg0, SSLSession arg1) {
			return true;
		}
	}

}
